package cn.always.xiajia.framework.mybatis.core.service.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.github.yulichang.base.MPJBaseServiceImpl;

import cn.always.xiajia.framework.common.util.ExtMapUtils;
import cn.always.xiajia.framework.mybatis.core.mapper.BaseMapperX;
import cn.always.xiajia.framework.mybatis.core.query.QueryWrapperX;
import cn.always.xiajia.framework.mybatis.core.service.BaseServiceX;

@SuppressWarnings("unused")
public class BaseServiceImplX<M extends BaseMapperX<T>, T> extends MPJBaseServiceImpl<M, T> implements BaseServiceX<T> {

	protected Log log = LogFactory.getLog(getClass());

	/**
	 * 删除
	 * 
	 * @param param
	 * @return
	 */
	@Override
	public boolean xjRemove(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return false;
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return SqlHelper.retBool(getBaseMapper().delete(queryWrapperX));
	}

	/**
	 * 根据 Wrapper，查询一条记录 <br/>
	 * <p>
	 * 结果集，如果是多个会抛出异常，随机取一条加上限制条件 wrapper.last("LIMIT 1")
	 * </p>
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public T xjGetOne(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return null;
		}
		return xjGetOne(param, true);
	}

	/**
	 * 根据 Wrapper，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param throwEx 有多个 result 是否抛出异常
	 */
	@Override
	public T xjGetOne(Map<String, Object> param, boolean throwEx) {
		if (ExtMapUtils.isEmpty(param)) {
			return null;
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectOne(queryWrapperX, throwEx);
	}

	/**
	 * 根据 Map，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public Map<String, Object> xjGetMap(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return Collections.emptyMap();
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return SqlHelper.getObject(log, getBaseMapper().selectMaps(queryWrapperX));
	}

	/**
	 * 根据 Wrapper，查询一条记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param mapper 转换函数
	 */
	@Override
	public <V> V xjGetObj(Map<String, Object> param, Function<? super Object, V> mapper) {
		if (ExtMapUtils.isEmpty(param)) {
			return null;
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return SqlHelper.getObject(log, listObjs(queryWrapperX, mapper));
	}

	/**
	 * 查询指定条件是否存在数据
	 *
	 * @see Wrappers#emptyWrapper()
	 */
	@Override
	public boolean xjExists(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return false;
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().exists(queryWrapperX);
	}

	/**
	 * 根据 Map 条件，查询总记录数
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public long xjCount(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return 0;
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return SqlHelper.retCount(getBaseMapper().selectCount(queryWrapperX));
	}

	/**
	 * 查询全部
	 * 
	 * @param param
	 * @return
	 */
	@Override
	public List<T> xjList(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return Collections.emptyList();
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectList(queryWrapperX);
	}

	/**
	 * 查询列表
	 *
	 * @param page 分页条件
	 * @param queryWrapper queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @return 列表数据
	 * @since 3.5.3.2
	 */
	@Override
	public List<T> xjList(IPage<T> page, Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return getBaseMapper().selectList(page, Wrappers.emptyWrapper());
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectList(page, queryWrapperX);
	}

	/**
	 * 翻页查询
	 *
	 * @param page 翻页对象
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public <E extends IPage<T>> E xjPage(E page, Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return getBaseMapper().selectPage(page, Wrappers.emptyWrapper());
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectPage(page, queryWrapperX);
	}

	/**
	 * 查询列表
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public List<Map<String, Object>> xjListMaps(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return Collections.emptyList();
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectMaps(queryWrapperX);
	}

	/**
	 * 查询列表
	 *
	 * @param page 分页条件
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @return 列表数据
	 * @since 3.5.3.2
	 */
	@Override
	public List<Map<String, Object>> xjListMaps(IPage<? extends Map<String, Object>> page, Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return getBaseMapper().selectMaps(page, Wrappers.emptyWrapper());
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectMaps(page, queryWrapperX);
	}

	/**
	 * 根据 Map 条件，查询全部记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public List<Object> xjListObjs(Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return Collections.emptyList();
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return listObjs(queryWrapperX, Function.identity());
	}

	/**
	 * 根据 Map 条件，查询全部记录
	 *
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 * @param mapper 转换函数
	 */
	@Override
	public <V> List<V> xjListObjs(Map<String, Object> param, Function<? super Object, V> mapper) {
		if (ExtMapUtils.isEmpty(param)) {
			return Collections.emptyList();
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectObjs(queryWrapperX).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
	}

	/**
	 * 翻页查询
	 *
	 * @param page 翻页对象
	 * @param queryWrapper 实体对象封装操作类
	 *            {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
	 */
	@Override
	public <E extends IPage<Map<String, Object>>> E xjPageMaps(E page, Map<String, Object> param) {
		if (ExtMapUtils.isEmpty(param)) {
			return getBaseMapper().selectMapsPage(page, Wrappers.emptyWrapper());
		}
		QueryWrapperX<T> queryWrapperX = new QueryWrapperX<>();
		queryWrapperX.buildByMap(param);
		return getBaseMapper().selectMapsPage(page, queryWrapperX);
	}
}